package cz.mzk.funnylib.dao.db;

import cz.mzk.funnylib.dao.BookCheckDAO;
import cz.mzk.funnylib.entities.BookCheck;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.List;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;

/**
 *
 * @author xrosecky
 */
public class BookCheckDAOImpl implements BookCheckDAO {

    private static String ADD_BOOK_CHECK = "INSERT INTO book_checks(name, isbn, date, user_id, library_id) VALUES(?, ?, ?, ?, ?)";
    private static String UPDATE_BOOK_CHECK = "UPDATE book_checks SET name = ?, isbn = ?, date = ?, user_id = ?, library_id = ? WHERE id = ?";
    private static String SELECT_BOOK_CHECKS_FOR_USER = "SELECT id, name, isbn, date, user_id, library_id FROM book_checks WHERE user_id = ?";
    private JdbcTemplate jdbcTemplate;

    public BookCheckDAOImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<BookCheck> getBookChecksForUser(Long userId) {
        return jdbcTemplate.query(SELECT_BOOK_CHECKS_FOR_USER, new Object[]{userId}, new BookCheckMapper());
    }

    public void persist(final BookCheck bookCheck) {
        if (bookCheck.getId() == null) {
            GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
            try {
                jdbcTemplate.update(new PreparedStatementCreator() {

                    @Override
                    public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
                        PreparedStatement preparedStatement = conn.prepareStatement(ADD_BOOK_CHECK, Statement.RETURN_GENERATED_KEYS);
                        preparedStatement.setString(1, bookCheck.getName());
                        preparedStatement.setString(2, bookCheck.getIsbn());
                        preparedStatement.setTimestamp(3, new Timestamp(bookCheck.getDate().getTime()));
                        preparedStatement.setLong(4, bookCheck.getUserId());
                        preparedStatement.setLong(5, bookCheck.getLibraryId());
                        return preparedStatement;
                    }
                }, keyHolder);
            } catch (DataIntegrityViolationException ex) {
                throw new RuntimeException("BookCheck already exists!", ex);
            }
            bookCheck.setId(keyHolder.getKey().longValue());
        } else {
            jdbcTemplate.update(new PreparedStatementCreator() {

                @Override
                public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
                    PreparedStatement preparedStatement = conn.prepareStatement(UPDATE_BOOK_CHECK);
                    preparedStatement.setString(1, bookCheck.getName());
                    preparedStatement.setString(2, bookCheck.getIsbn());
                    preparedStatement.setTimestamp(3, new Timestamp(bookCheck.getDate().getTime()));
                    preparedStatement.setLong(4, bookCheck.getUserId());
                    preparedStatement.setLong(5, bookCheck.getLibraryId());
                    return preparedStatement;
                }
            });
        }
    }

    public class BookCheckMapper implements RowMapper<BookCheck> {

        @Override
        public BookCheck mapRow(ResultSet rs, int rowNum) throws SQLException {
            BookCheck bookCheck = new BookCheck();
            bookCheck.setId(rs.getLong(1));
            bookCheck.setName(rs.getString(2));
            bookCheck.setIsbn(rs.getString(3));
            bookCheck.setUserId(rs.getLong(4));
            bookCheck.setLibraryId(rs.getLong(5));
            return bookCheck;
        }
    }
}
